package com.shycloud.mido.member.service.impl;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shycloud.mido.common.core.exception.BusinessException;
import com.shycloud.mido.common.pay.alipay.AlipayConfig;
import com.shycloud.mido.common.pay.alipaynew.AliPayResult;
import com.shycloud.mido.common.pay.wxpay.WXUtils.MyConfig;
import com.shycloud.mido.common.pay.wxpay.WXUtils.WXPayNative;
import com.shycloud.mido.common.pay.wxpaynew.WXPayResult;
import com.shycloud.mido.common.util.NetworkUtil;
import com.shycloud.mido.common.util.SnowFlakeUtil;
import com.shycloud.mido.member.api.entity.BasicComboGoods;
import com.shycloud.mido.member.api.entity.BasicComboInfo;
import com.shycloud.mido.member.api.entity.BasicGoodsCategory;
import com.shycloud.mido.member.api.entity.BasicGoodsInfo;
import com.shycloud.mido.member.api.entity.HardwareSale;
import com.shycloud.mido.member.api.entity.MemberOrder;
import com.shycloud.mido.member.api.entity.MemberOrderDetail;
import com.shycloud.mido.member.api.entity.PersonalCombVO;
import com.shycloud.mido.member.api.vo.BasicGoodsInfoVO;
import com.shycloud.mido.member.api.vo.GoodsInfoVO;
import com.shycloud.mido.member.api.vo.MallCreateOrderVO;
import com.shycloud.mido.member.api.vo.MasterPriceVO;
import com.shycloud.mido.member.api.vo.MemberOrderVO;
import com.shycloud.mido.member.api.vo.OnlineCourePriceVO;
import com.shycloud.mido.member.api.vo.OnlineCourseOrderVO;
import com.shycloud.mido.member.api.vo.ProductsComboVO;
import com.shycloud.mido.member.api.vo.combo.ComboInfo;
import com.shycloud.mido.member.api.vo.combo.GoodsInfo;
import com.shycloud.mido.member.constants.ShoppingStockConstants;
import com.shycloud.mido.member.mapper.BasicComboGoodsMapper;
import com.shycloud.mido.member.mapper.BasicGoodsCategoryMapper;
import com.shycloud.mido.member.mapper.BasicGoodsInfoMapper;
import com.shycloud.mido.member.mapper.BasicProductsComboMapper;
import com.shycloud.mido.member.mapper.MemberOrderDetailMapper;
import com.shycloud.mido.member.mapper.MemberOrderMapper;
import com.shycloud.mido.member.service.PayService;
import com.shycloud.mido.member.service.ShoppingMallService;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author Xiaoxing Yu
 * @date 2020/9/1
 **/
@Slf4j
@Service
@AllArgsConstructor
public class ShoppingMallServiceImpl extends ServiceImpl<BasicProductsComboMapper, BasicComboInfo> implements ShoppingMallService {

	private BasicProductsComboMapper comboMapper;
	/** Order Mapper */
	private MemberOrderMapper orderMapper;

	/** Goods Mapper */
	private BasicGoodsInfoMapper goodsInfoMapper;

	/** Combo-Goods mapping Mapper */
	private BasicComboGoodsMapper comboGoodsMapper;

	/** Goods-category Mapper */
	private BasicGoodsCategoryMapper categoryMapper;

	/** Pay Service */
	private PayService payService;

	/** Order Detail 订单详情 Mapper */
	private MemberOrderDetailMapper orderDetailMapper;

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean addNewCombo(ProductsComboVO comboVO) {
		try {
			BasicComboInfo comboEntity = new BasicComboInfo();
			BeanUtils.copyProperties(comboVO, comboEntity);

			comboEntity.setCreateTime(LocalDateTime.now());
			comboEntity.setUpdateTime(LocalDateTime.now());
			comboEntity.setStatus(ShoppingStockConstants.ONE_YES);    //默认上架
			comboEntity.setGraceType(comboVO.getGraceType());

			int comboInsert = comboMapper.insert(comboEntity);

			if (comboInsert != 1) throw new BusinessException("添加套餐失败！");

			//处理购买部分
			if (comboVO.getGoodsList() == null) throw new BusinessException("商品不可为空");

			for (GoodsInfo goodsInfo : comboVO.getGoodsList()) {
				BasicComboGoods mappingEntity = new BasicComboGoods();
				mappingEntity.setComboId(comboEntity.getId());
				mappingEntity.setGiftFlag(ShoppingStockConstants.ZERO_NO);
				mappingEntity.setGoodsId(goodsInfo.getGoodsId());
				if (goodsInfo.getQuantity() == null || goodsInfo.getQuantity() == 0) continue;
				mappingEntity.setQuantity(goodsInfo.getQuantity());

				int buyInsert = comboGoodsMapper.insert(mappingEntity);
				if (buyInsert != 1) throw new BusinessException("添加套餐失败！");
			}

			//处理赠送部分, 如果选择了折扣，赠送是空，所以这里要判断
			if (comboVO.getGiftGoodsList() != null) {
				for (GoodsInfo goodsInfo : comboVO.getGiftGoodsList()) {
					BasicComboGoods mappingEntity = new BasicComboGoods();
					mappingEntity.setComboId(comboEntity.getId());
					mappingEntity.setGiftFlag(ShoppingStockConstants.ONE_YES);
					mappingEntity.setGoodsId(goodsInfo.getGoodsId());
					if (goodsInfo.getQuantity() == null || goodsInfo.getQuantity() == 0) continue;
					mappingEntity.setQuantity(goodsInfo.getQuantity());

					int giftInsert = comboGoodsMapper.insert(mappingEntity);
					if (giftInsert != 1) throw new BusinessException("添加套餐失败！");
				}
			}

		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw new BusinessException("添加套餐失败！");
		}

		return true;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean editCombo(ProductsComboVO comboVO) {
		try {
			BasicComboInfo comboEntity = new BasicComboInfo();
			BeanUtils.copyProperties(comboVO, comboEntity);

			comboEntity.setId(comboVO.getComboId());
			comboEntity.setCreateTime(LocalDateTime.now());
			comboEntity.setUpdateTime(LocalDateTime.now());
			comboEntity.setGraceType(comboVO.getGraceType());

			int comboInsert = comboMapper.updateById(comboEntity);
			if (comboInsert != 1) throw new BusinessException("编辑套餐失败！");

			//删除之前comboId对应的所有goodsId-comboId mapping关系(如果有的话)，下面全量覆盖重新添加
			comboGoodsMapper.delete(
					new QueryWrapper<BasicComboGoods>().eq("combo_id", comboVO.getComboId()));

			//处理购买部分
			if (comboVO.getGoodsList() != null) {
				for (GoodsInfo goodsInfo : comboVO.getGoodsList()) {
					BasicComboGoods mappingEntity = new BasicComboGoods();
					mappingEntity.setComboId(comboEntity.getId());
					mappingEntity.setGiftFlag(ShoppingStockConstants.ZERO_NO);
					mappingEntity.setGoodsId(goodsInfo.getGoodsId());
					if (goodsInfo.getQuantity() == null || goodsInfo.getQuantity() == 0) continue;
					mappingEntity.setQuantity(goodsInfo.getQuantity());

					int buyInsert = comboGoodsMapper.insert(mappingEntity);
					if (buyInsert != 1) throw new BusinessException("编辑套餐失败！");
				}
			}

			//处理赠送部分
			if (comboVO.getGiftGoodsList() != null) {
				for (GoodsInfo goodsInfo : comboVO.getGiftGoodsList()) {
					BasicComboGoods mappingEntity = new BasicComboGoods();
					mappingEntity.setComboId(comboEntity.getId());
					mappingEntity.setGiftFlag(ShoppingStockConstants.ONE_YES);
					mappingEntity.setGoodsId(goodsInfo.getGoodsId());
					if (goodsInfo.getQuantity() == null || goodsInfo.getQuantity() == 0) continue;
					mappingEntity.setQuantity(goodsInfo.getQuantity());

					int giftInsert = comboGoodsMapper.insert(mappingEntity);
					if (giftInsert != 1) throw new BusinessException("编辑套餐失败！");
				}
			}
		} catch (BusinessException e) {
			log.error(e.getMessage(), e);
			throw e;
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw new BusinessException("编辑套餐失败！");
		}

		return true;
	}

	@Override
	public Boolean triggerCombo(ProductsComboVO comboVO) {
		BasicComboInfo comboEntity = comboMapper.selectOne(
				new QueryWrapper<BasicComboInfo>().eq("id", comboVO.getComboId()));

		comboEntity.setStatus(comboVO.getStatus());

		return comboMapper.updateById(comboEntity) == 1 ? true : false;
	}

	@Override
	public Boolean deleteCombo(Integer comboId) {
		return comboMapper.deleteById(comboId) == 1 ? true : false;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean addPersonalCombo(PersonalCombVO comboVO) {
		try {
			BasicComboInfo comboEntity = new BasicComboInfo();

			comboEntity.setCreateTime(LocalDateTime.now());
			comboEntity.setUpdateTime(LocalDateTime.now());
			//先存optId
			comboEntity.setOptId(comboVO.getOptId());
			comboEntity.setIsPersonal(ShoppingStockConstants.ONE_YES);
			comboEntity.setComboName(comboVO.getComboName());

			int comboInsert = comboMapper.insert(comboEntity);
			if (comboInsert != 1) throw new BusinessException("添加个人套餐失败！");

			BasicGoodsInfo masterInfo = goodsInfoMapper.selectOne(
					new QueryWrapper<BasicGoodsInfo>()
//							.eq("product_id", ShoppingStockConstants.MASTER_PRODUCT_ID)
							.eq("id", comboVO.getMasterGoodsId()));
			BasicGoodsInfo onlineCourseInfo = goodsInfoMapper.selectOne(
					new QueryWrapper<BasicGoodsInfo>().eq(
							"product_id", ShoppingStockConstants.ONLINE_COURSE_PRODUCT_ID));

			//处理纠错大师
			BasicComboGoods masterMapping = new BasicComboGoods();
			masterMapping.setComboId(comboEntity.getId());
			masterMapping.setGiftFlag(ShoppingStockConstants.ZERO_NO);
			masterMapping.setGoodsId(masterInfo.getId());
			masterMapping.setQuantity(ShoppingStockConstants.ONE);

			int masterInsert = comboGoodsMapper.insert(masterMapping);
			if (masterInsert != 1) throw new BusinessException("添加个人套餐失败！");

			//处理在线课
			BasicComboGoods onlineCMapping = new BasicComboGoods();
			onlineCMapping.setComboId(comboEntity.getId());
			onlineCMapping.setGiftFlag(ShoppingStockConstants.ZERO_NO);
			onlineCMapping.setGoodsId(onlineCourseInfo.getId());

			if (comboVO.getOnlineCourseTime() % onlineCourseInfo.getUnitCount() != 0) {
				throw new BusinessException("请输入" + onlineCourseInfo.getUnitCount() + "的整数倍时长!");
			} else {
				onlineCMapping.setQuantity(comboVO.getOnlineCourseTime() / onlineCourseInfo.getUnitCount());
			}

			int onlineCInsert = comboGoodsMapper.insert(onlineCMapping);
			if (onlineCInsert != 1) throw new BusinessException("添加个人套餐失败！");
		} catch (Exception e) {
			throw new BusinessException("添加个人套餐失败!");
		}

		return true;
	}

	@Override
	public List<PersonalCombVO> getPersonalCombo(Integer optId) {
		List<PersonalCombVO> returnList = new ArrayList<>();

		List<BasicComboInfo> comboInfoList = comboMapper.selectList(
				new QueryWrapper<BasicComboInfo>().eq("opt_id", optId));

		List<BasicGoodsInfo> masterInfoList = goodsInfoMapper.selectList(
				new QueryWrapper<BasicGoodsInfo>()
						.eq("product_id", ShoppingStockConstants.MASTER_PRODUCT_ID));

		BasicGoodsInfo onlineCourseInfo = goodsInfoMapper.selectById(12);

		for (BasicComboInfo comboInfo : comboInfoList) {
			List<BasicComboGoods> mappingList = comboGoodsMapper.selectList(
					new QueryWrapper<BasicComboGoods>().eq("combo_id", comboInfo.getId()));

			PersonalCombVO returnVO = new PersonalCombVO();

			for (BasicComboGoods mapping : mappingList) {
				Integer curId = mapping.getGoodsId();

				if (curId == onlineCourseInfo.getId()) {
					returnVO.setOnlineCourseTime(onlineCourseInfo.getUnitCount() * mapping.getQuantity());
				}

				for (BasicGoodsInfo masterInfo : masterInfoList) {
					if (curId == masterInfo.getId()) {
						returnVO.setMasterDuration(masterInfo.getUnitCount());
						returnVO.setMasterGoodsId(curId);
					}
				}
			}

			returnVO.setComboName(comboInfo.getComboName());
			returnList.add(returnVO);
		}

		return returnList;
	}

	@Override
	public List<ProductsComboVO> getAllComboList(boolean onlyActive) {
		QueryWrapper wrapper = new QueryWrapper<BasicComboInfo>();
		if (onlyActive) wrapper.eq("status", "1");

		List<BasicComboInfo> comboList =
				comboMapper.selectList(wrapper);

		List<ProductsComboVO> returnList = new ArrayList<>();

		for (BasicComboInfo combo : comboList) {
			List<BasicComboGoods> mappingList = comboGoodsMapper.selectList(
					new QueryWrapper<BasicComboGoods>().eq("combo_id", combo.getId()));

			List<GoodsInfo> goodsList = new ArrayList<>();
			List<GoodsInfo> giftGoodsList = new ArrayList<>();

			for (BasicComboGoods mapping : mappingList) {
				GoodsInfo goods = new GoodsInfo();
				Integer goodsId = mapping.getGoodsId();
				goods.setGoodsId(goodsId);
				goods.setQuantity(mapping.getQuantity());
				BasicGoodsInfo goodsInfo = goodsInfoMapper.selectOne(
						new QueryWrapper<BasicGoodsInfo>().eq("id", goodsId));
				if (goodsInfo == null) continue;
				goods.setGoodsName(goodsInfo.getName());

				if (mapping.getGiftFlag().equals("0")) {
					goodsList.add(goods);
				} else {
					giftGoodsList.add(goods);
				}
			}

			ProductsComboVO comboVO = new ProductsComboVO();
			BeanUtils.copyProperties(combo, comboVO);

			comboVO.setComboId(combo.getId());
			comboVO.setGoodsList(goodsList);
			comboVO.setGiftGoodsList(giftGoodsList);
			returnList.add(comboVO);
		}

		return returnList;
	}

	@Override
	public IPage<MemberOrderVO> pageOrders(
			Page page, String startDate, String endDate, String paymentMethod,
			String orderNo, String status, Integer optId, Integer orgId) {
		startDate = checkDateFormat(startDate);
		endDate = checkDateFormat(endDate);

		IPage<MemberOrderVO> returnIPage = null;

		returnIPage = orderMapper.pageOrders(
				page, ShoppingStockConstants.ORDER_TYPE_ADMIN,
				startDate, endDate, paymentMethod,
				orderNo == null || orderNo.length() == 0 ? null : Long.valueOf(orderNo),
				status, optId, orgId);

		for (MemberOrderVO returnVO : returnIPage.getRecords()) {
			List<MemberOrderDetail> detailList = orderDetailMapper.selectList(
					new QueryWrapper<MemberOrderDetail>().eq("order_no", returnVO.getOrderNo()));
			returnVO.setOrderDetailList(detailList);
		}

		return returnIPage;
	}

	private String checkDateFormat(String dateString) throws BusinessException {
		if (dateString != null) {
			try {
				if (dateString.length() == 0) return null;
				Date date = new SimpleDateFormat("yyyy-MM-dd").parse(dateString);
				return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
			} catch (ParseException e) {
				log.error(e.getMessage(), e);
				throw new BusinessException("请检查日期格式是否为yyyy-MM-dd!");
			}
		}

		return null;
	}

	@Override
	public List<BasicGoodsInfo> getGoods(Integer categoryId, String goodsName) {
		QueryWrapper wrapper = new QueryWrapper<BasicGoodsInfo>();
		if (categoryId != null) wrapper.eq("category_id", categoryId);
		if (goodsName != null) {
			wrapper.like("name", goodsName);
		}
		return goodsInfoMapper.selectList(wrapper);
	}

	@Override
	public Boolean editGoods(GoodsInfoVO goodsInfoVO) {
		BasicGoodsInfo goodsEntity = goodsInfoMapper.selectOne(
				new QueryWrapper<BasicGoodsInfo>().eq("id", goodsInfoVO.getGoodsId()));

		Integer newUnitCount = goodsInfoVO.getUnitCount();
		goodsEntity.setExpireDuration(goodsInfoVO.getExpireDuration());
		goodsEntity.setMinPurchase(goodsInfoVO.getMinPurchase());
		goodsEntity.setUnitCount(newUnitCount);
		goodsEntity.setUpdateTime(LocalDateTime.now());
		//更新人存运营商手机号或者optId TODO
//		goodsEntity.setUpdatedBy();
		goodsEntity.setGoodsPrice(goodsInfoVO.getGoodsPrice());

		//更改名称
		String name = goodsEntity.getName();
		for (int i = 0; i < name.length(); i++) {
			if (String.valueOf(name.charAt(i)).matches("[0-9]")) {
				String productName = name.substring(0, i);
				StringBuffer newName = new StringBuffer(productName);
				newName.append(newUnitCount);
				newName.append(goodsEntity.getUnit());
				goodsEntity.setName(newName.toString());
				break;
			}
		}

		return goodsInfoMapper.updateById(goodsEntity) == 1 ? true : false;
	}

	@Override
	public List<GoodsInfoVO> getEditableGoods() {
		return goodsInfoMapper.selectEditableGoods();
	}

	@Override
	public Map getVirtualGoods() {
		List<GoodsInfoVO> goodsList = goodsInfoMapper.selectEditableGoods();
		Map<String, Object> map = new HashMap();
		List<MasterPriceVO> masterList = new ArrayList<>();

		for (GoodsInfoVO vo : goodsList) {
			if (vo.getGoodsName().contains(ShoppingStockConstants.ONLINE_COURSE_CHINESE)) {
				OnlineCourePriceVO onlineCourePriceVO = new OnlineCourePriceVO();
				onlineCourePriceVO.setName(vo.getGoodsName());
				onlineCourePriceVO.setPrice(vo.getGoodsPrice());
				onlineCourePriceVO.setDuration(vo.getUnitCount());
				onlineCourePriceVO.setMinMinutes(vo.getMinPurchase() * vo.getUnitCount());
				onlineCourePriceVO.setGoodsId(vo.getGoodsId());
				onlineCourePriceVO.setUnit(vo.getUnit());

				map.put("onlineCourse", onlineCourePriceVO);
			} else if (vo.getGoodsName().contains(ShoppingStockConstants.MASTER_CHINESE)) {
				MasterPriceVO masterPriceVO = new MasterPriceVO();
				masterPriceVO.setName(vo.getGoodsName());
				masterPriceVO.setPrice(vo.getGoodsPrice());
				masterPriceVO.setDuration(vo.getExpireDuration());
				masterPriceVO.setMinPurchase(vo.getMinPurchase());
				masterPriceVO.setGoodsId(vo.getGoodsId());
				masterPriceVO.setUnit(vo.getUnit());

				masterList.add(masterPriceVO);
			}
		}

		map.put("masterList", masterList);

		return map;
	}

	@Override
	public Boolean editVirtualGoods(Map map) {
		GoodsInfoVO goodsInfoVO = new GoodsInfoVO();

		if (map.get("onlineCourse") != null) {
			Map innerMap = (Map) map.get("onlineCourse");
			OnlineCourePriceVO onlineCourePriceVO =
					JSON.parseObject(JSON.toJSONString(innerMap), OnlineCourePriceVO.class);

			goodsInfoVO.setGoodsId(onlineCourePriceVO.getGoodsId());
			goodsInfoVO.setMinPurchase(onlineCourePriceVO.getMinMinutes() / onlineCourePriceVO.getDuration());
			goodsInfoVO.setGoodsPrice(onlineCourePriceVO.getPrice());
			goodsInfoVO.setUnitCount(onlineCourePriceVO.getDuration());
		} else if (map.get("master") != null) {
			Map innerMap = (Map) map.get("master");
			MasterPriceVO masterPriceVO =
					JSON.parseObject(JSON.toJSONString(innerMap), MasterPriceVO.class);

			goodsInfoVO.setGoodsId((masterPriceVO.getGoodsId()));
			goodsInfoVO.setMinPurchase((masterPriceVO.getMinPurchase()));
			goodsInfoVO.setGoodsPrice((masterPriceVO.getPrice()));
			goodsInfoVO.setUnitCount((masterPriceVO.getDuration()));
		}

		return this.editGoods(goodsInfoVO);
	}

	@Override
	public BigDecimal calOnlineCoursePrice(Integer duration) {
		BasicGoodsInfo goodsInfo = goodsInfoMapper.selectOne(
				new QueryWrapper<BasicGoodsInfo>().likeRight("name", "在线课"));

		if (duration % goodsInfo.getUnitCount() != 0) {
			throw new BusinessException("请输入" + goodsInfo.getUnitCount() + "的整数倍时长!");
		}

		BigDecimal count = new BigDecimal(duration).divide(new BigDecimal(goodsInfo.getUnitCount()));

		return goodsInfo.getGoodsPrice().multiply(count);
	}

	@Override
	public BigDecimal calMasterPrice(Integer duration) {
		BasicGoodsInfo goodsInfo = goodsInfoMapper.selectOne(
				new QueryWrapper<BasicGoodsInfo>()
						.like("name", "纠错大师")
						.eq("unit_count", duration));

		return goodsInfo.getGoodsPrice();
	}

	@Override
	public List<BasicGoodsInfo> getMasterGoods() {
		List<BasicGoodsInfo> infoList = goodsInfoMapper.selectList(
				new QueryWrapper<BasicGoodsInfo>()
						.like("name", "纠错大师"));
		return infoList;
	}

	@Override
	public List<BasicGoodsCategory> getGoodsCategory() {
		return categoryMapper.selectList(
				new QueryWrapper<BasicGoodsCategory>());
	}

	@Override
	public BasicGoodsInfo getPriceByGoodsId(Integer goodsId) {
		return goodsInfoMapper.selectOne(new QueryWrapper<BasicGoodsInfo>().eq("id", goodsId));
	}

	/**
	 * 后台快乐斑马创建订单
	 *
	 * @param orderVO
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Map createOrder(MallCreateOrderVO orderVO, HttpServletRequest request) {
		Map returnMap = null;
		if (orderVO.getPrice() == null ||
				(orderVO.getPrice().compareTo(new BigDecimal(0)) == 0))
			throw new BusinessException("订单价格不能为空，请添加商品再确认支付!");

		BigDecimal payTotal = orderVO.getPrice();

		try {
			//先检验订单价格是否正确
			BigDecimal calSum = new BigDecimal(0);
			for (GoodsInfo goodsInfo : orderVO.getGoodsList()) {
				calSum = calSum.add(goodsInfo.getGoodsPrice().multiply(new BigDecimal(goodsInfo.getQuantity())));
			}

			for (ComboInfo comboInfo : orderVO.getComboList()) {
				calSum = calSum.add(comboInfo.getComboPrice().multiply(new BigDecimal(comboInfo.getQuantity())));
			}

			if (orderVO.getOnlineCourse() != null && orderVO.getOnlineCourse().getTotalPrice() != null) {
				calSum = calSum.add(orderVO.getOnlineCourse().getTotalPrice());
			}

			log.info("下单总金额计算为: " + calSum.toString());

			if (calSum.compareTo(payTotal) != 0) throw new BusinessException("总支付金额校验失败!");

			returnMap = new HashMap();

			Integer machineId = ShoppingStockConstants.getConsistentHash(NetworkUtil.getHostIp());
			long orderNo = new SnowFlakeUtil(1, machineId).nextId();
			log.info(": " + orderNo);

			returnMap.put("orderNo", String.valueOf(orderNo));

			MemberOrder entity = new MemberOrder();
			entity.setOrderNo(orderNo);
			entity.setOrderType(ShoppingStockConstants.ORDER_TYPE_ADMIN);
			entity.setPaymentMethod(orderVO.getPaymentMethod());
			entity.setCreateTime(LocalDateTime.now());
			if (orderVO.getOptId() != null) entity.setOptId(orderVO.getOptId());
			else if (orderVO.getOrgId() != null) entity.setOrgId(orderVO.getOrgId());
			//运营商后台账号暂时没有memberId，这里不用set
			entity.setPrice(payTotal);

			if (orderMapper.insert(entity) != 1) throw new BusinessException("创建订单失败");

			for (GoodsInfo goodsInfo : orderVO.getGoodsList()) {
				MemberOrderDetail orderDetailEntity = new MemberOrderDetail();
				orderDetailEntity.setOrderNo(orderNo);
				orderDetailEntity.setGoodsId(goodsInfo.getGoodsId());
				orderDetailEntity.setGoodsCount(goodsInfo.getQuantity());

				if (orderDetailMapper.insert(orderDetailEntity) != 1) throw new BusinessException("创建订单失败");
			}

			for (ComboInfo comboInfo : orderVO.getComboList()) {
				MemberOrderDetail orderDetailEntity = new MemberOrderDetail();
				orderDetailEntity.setOrderNo(orderNo);
				orderDetailEntity.setComboId(comboInfo.getComboId());
				orderDetailEntity.setComboCount(comboInfo.getQuantity());

				if (orderDetailMapper.insert(orderDetailEntity) != 1) throw new BusinessException("创建订单失败");
			}

			//处理在线课购买逻辑
			if (orderVO.getOnlineCourse() != null && orderVO.getOnlineCourse().getTotalPrice() != null) {
				OnlineCourseOrderVO onlineCourseOrderVO = orderVO.getOnlineCourse();
				MemberOrderDetail orderDetailEntity = new MemberOrderDetail();
				orderDetailEntity.setOrderNo(orderNo);
				orderDetailEntity.setGoodsId(onlineCourseOrderVO.getGoodsId());
				//此处要保证总价和单价能整除
				orderDetailEntity.setGoodsCount(
						onlineCourseOrderVO.getTotalPrice().divide(
								onlineCourseOrderVO.getUnitPrice()).intValue());

				if (orderDetailMapper.insert(orderDetailEntity) != 1) throw new BusinessException("创建订单失败");
			}

			//预生成订单，并生成二维码地址返回
			if (orderVO.getPaymentMethod().equals(ShoppingStockConstants.PAY_TYPE_WECHAT)) {
				Map respMap = payService.wxWebPrePay(request, String.valueOf(orderNo), payTotal);
				if (respMap.get("code_url") != null) returnMap.put("codeUrl", respMap.get("code_url"));
				else throw new BusinessException("微信支付创建订单失败!");
			} else if (orderVO.getPaymentMethod().equals(ShoppingStockConstants.PAY_TYPE_ALIPAY)) {
				Map respMap = payService.alipayWebPrePay(String.valueOf(orderNo), payTotal);
				AlipayTradePrecreateResponse response = (AlipayTradePrecreateResponse) respMap.get("response");
				if (response.getQrCode() != null) returnMap.put("codeUrl", response.getQrCode());
				else throw new BusinessException("支付宝支付创建订单失败!");
			}
		} catch (BusinessException e) {
			throw e;
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw new BusinessException("创建订单失败");
		}

		return returnMap;
	}

	/**
	 * 添加商品
	 *
	 * @param goodsInfoVO
	 * @return java.lang.Boolean
	 * @author nianhua.jiang
	 * @date 2020/9/24 10:42
	 **/
	@Override
	public Boolean addGoods(BasicGoodsInfoVO goodsInfoVO) {

		BasicGoodsInfo goodsInfo = new BasicGoodsInfo();

		BeanUtils.copyProperties(goodsInfoVO, goodsInfo);
		//初期库存
		Integer targetCount = 0;

		List<Map<String, Integer>> wareHouseIdList = goodsInfoVO.getWareHouseIdList();

		for (Map<String, Integer> stringIntegerMap : wareHouseIdList) {
			//循环累加总计库存
			Integer count = stringIntegerMap.get("count");
			targetCount += count;
		}
		//添加初级库存
		goodsInfo.setStockQuantity(targetCount);
		//新增商品
		return goodsInfoMapper.insert(goodsInfo) == 1;
	}

	@Override
	public List<BasicComboGoods> getGoodsByCombo(Integer comboId) {
		return comboGoodsMapper.selectList(
				new QueryWrapper<BasicComboGoods>().eq("combo_id", comboId));
	}

	@Override
	public List<BasicGoodsInfo> matchGoodsInfoByKeyword(String keyword) {
		return goodsInfoMapper.selectList(
				new QueryWrapper<BasicGoodsInfo>().like("name", keyword));
	}

	@Override
	public Map<String, String> queryOrderPayment(String paymentMethod, String orderNo) {
		Map returnMap = new HashMap();
		returnMap.put("orderNo", orderNo);

		//支付宝支付
		if ("1".equals(paymentMethod)) {
			try {
				AlipayClient alipayClient = new DefaultAlipayClient(
						AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY,
						AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);

				AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();

				AlipayTradeQueryModel model = new AlipayTradeQueryModel();

				model.setOutTradeNo(orderNo);
				model.setTradeNo(null);
				request.setBizModel(model);

				AlipayTradeQueryResponse response = alipayClient.execute(request);
				if (response.isSuccess()) {
					log.info("调用成功");
					returnMap.put("callResult", true);

					String payCode = null;
					String status = response.getTradeStatus();
					if (status.equals(AliPayResult.WAIT_BUYER_PAY.getState())) {
						payCode = "2";
						returnMap.put("comments", "等待用户付款");
					} else if (status.equals(AliPayResult.TRADE_CLOSED.getState())) {
						payCode = "0";
						returnMap.put("comments", "交易失败");
					} else if (status.equals(AliPayResult.TRADE_SUCCESS.getState()) ||
							status.equals(AliPayResult.TRADE_FINISHED.getState())) {
						payCode = "1";
						returnMap.put("comments", "交易成功");
					}

					returnMap.put("description", response.getTradeStatus());
					returnMap.put("payCode", payCode);
				} else {
					log.error("调用失败");
					returnMap.put("callResult", true);
					returnMap.put("comments", "交易不存在或用户还未扫码拉起支付!");
					returnMap.put("payCode", "2");
				}
			} catch (AlipayApiException e) {
				log.error(e.getMessage(), e);
				returnMap.put("callResult", false);
			} catch (Exception e) {
				log.error(e.getMessage(), e);
				returnMap.put("callResult", false);
			}
			//微信支付
		} else if ("2".equals(paymentMethod)) {
			try {
				Map respMap = new HashMap<>();
				MyConfig config = new MyConfig();

				WXPayNative wxpay = new WXPayNative(config);
				Map<String, String> data = new HashMap<String, String>();
				data.put("out_trade_no", orderNo);
				// 此处指定为扫码支付
				try {
					respMap = wxpay.unifiedOrder(data, true);
					log.info("wx查询结果返回为: " + JSONObject.toJSONString(returnMap));
				} catch (Exception e) {
					log.error(e.getMessage(), e);
					log.error((String) respMap.get("err_code"));
					log.error("查询失败，请联系管理员");
				}
				if ("FAIL".equals(respMap.get("result_code"))) {
					log.error((String) respMap.get("err_code"));
					log.error("查询失败，请联系管理员");

					returnMap.put("callResult", true);
					returnMap.put("payCode", "2");
					returnMap.put("orderNo", orderNo);
					returnMap.put("comments", "交易不存在或用户还未扫码拉起支付!");
				} else if ("SUCCESS".equals(respMap.get("result_code"))) {
					String tradeStatus = (String) respMap.get("trade_state");
					String payCode = null;
					if (tradeStatus.equals(WXPayResult.CLOSED.getState()) ||
							tradeStatus.equals(WXPayResult.REFUND.getState()) ||
							tradeStatus.equals(WXPayResult.CLOSED.getState()) ||
							tradeStatus.equals(WXPayResult.PAYERROR.getState())) {
						payCode = "0";    //表示支付失败
					} else if (tradeStatus.equals(WXPayResult.SUCCESS.getState())) {
						payCode = "1";    //表示支付成功
					} else if (tradeStatus.equals(WXPayResult.NOTPAY.getState()) ||
							tradeStatus.equals(WXPayResult.USERPAYING.getState())) {
						payCode = "2";    //表示正在等待支付
					}

					returnMap.put("callResult", true);
					returnMap.put("payCode", payCode);
					returnMap.put("status", tradeStatus);
					returnMap.put("description", respMap.get("trade_state_desc"));
					returnMap.put("orderNo", respMap.get("out_trade_no"));
				}
			} catch (Exception e) {
				log.error(e.getMessage(), e);
				throw new BusinessException("查询失败，请联系管理员");
			}
		}

		return returnMap;
	}

	@Override
	public Boolean deleteOrder(Long orderNo) {
		return orderMapper.deleteById(orderNo) == 1 ? true : false;
	}

	//TODO ===========================2020/11/17 nianhua.jiang ADD START =============================================//

	/**
	 * 添加新套餐(H5页面用) 后台管理 -> 商品管理 -> 硬件销售项目 -> 新增项目
	 *
	 * @param entity
	 * @return java.lang.Boolean
	 * @author nianhua.jiang
	 * @date 2020/11/17 10:21
	 **/
	@Override
	@Transactional(rollbackFor = Exception.class, timeout = 36000)
	public Boolean addNewComboByH5(HardwareSale entity) {

		//1.添加套餐
		BasicComboInfo basicComboInfo = new BasicComboInfo();
		//套餐名称
		basicComboInfo.setComboName(entity.getItemName());
		//项目类型
		basicComboInfo.setItemType(entity.getItemType());
		//项目价格(折后价)
		basicComboInfo.setSalePrice(entity.getItemPrice());
		//分账价格
		basicComboInfo.setBonus(entity.getBonus());
		//项目排序
		basicComboInfo.setSort(entity.getSort());
		//是否允许运营商自定义名称
		basicComboInfo.setIsCustomizeName(entity.getIsCustomizeName());
		//是否允许运营商自定义可见
		basicComboInfo.setIsCustomizeVisible(entity.getIsCustomizeVisible());
		//是否H5相关
		basicComboInfo.setIsH5("1");
		//创建时间
		basicComboInfo.setCreateTime(LocalDateTime.now());
		//更新时间
		basicComboInfo.setUpdateTime(LocalDateTime.now());
		//纠错大师时长
		basicComboInfo.setHardwareDuration(entity.getHardwareDuration());
		//VIP时长
		basicComboInfo.setVipDuration(entity.getVipDuration());
		//快乐贝数量
		basicComboInfo.setGold(entity.getGold());

		//添加套餐
		if (comboMapper.insert(basicComboInfo) != 1) {
			throw new BusinessException("添加套餐失败，请联系管理员");
		}

		//2.添加商品
		//纠错大师权限商品ID
		Integer hardWareId = 0;
		//VIP权限商品ID
		Integer vipId = 0;
		//虚拟币商品ID
		Integer goldId = 0;

		//查重商品,VIP 使用权限的 productid 为1(固定)
		if (entity.getVipDuration() != null) {
			List<BasicGoodsInfo> basicGoodsInfoVipList = goodsInfoMapper.selectList(new QueryWrapper<BasicGoodsInfo>()
					.eq("product_id", 1)
					.eq("expire_duration", entity.getVipDuration()));
			if (basicGoodsInfoVipList.size() != 0) {
				vipId = basicGoodsInfoVipList.get(0).getId();
			} else {
				// 新增VIP商品
				vipId = insertGoodsInfo(entity, "VIP会员权限", 1, "天");
			}
		}

		//查重商品,纠错大师使用权限的 productid 为2(固定)
		List<BasicGoodsInfo> basicGoodsInfoList = goodsInfoMapper.selectList(new QueryWrapper<BasicGoodsInfo>()
				.eq("product_id", 2)
				.eq("expire_duration", entity.getHardwareDuration()));
		if (basicGoodsInfoList.size() != 0) {
			hardWareId = basicGoodsInfoList.get(0).getId();
		} else {
			hardWareId = insertGoodsInfo(entity, "纠错大师权限", 2, "天");
		}

		//查重商品,虚拟币的 productid 为3(固定)
		if (entity.getGold() != null) {
			List<BasicGoodsInfo> basicGoodsInfoGoldList = goodsInfoMapper.selectList(new QueryWrapper<BasicGoodsInfo>()
					.eq("product_id", 3)
					.eq("unit_count", entity.getGold()));
			if (basicGoodsInfoGoldList.size() != 0) {
				goldId = basicGoodsInfoGoldList.get(0).getId();
			} else {
				// 新增VIP商品
				goldId = insertGoodsInfo(entity, "快乐贝", 1, "个");
			}
		}

		//添加套餐-纠错大师权限关联关系

		insertBasicComboGoods(basicComboInfo.getId(), hardWareId);
		//添加套餐-VIP权限关联关系
		insertBasicComboGoods(basicComboInfo.getId(), vipId);
		//添加套餐-虚拟币关联关系
		insertBasicComboGoods(basicComboInfo.getId(), goldId);

		return true;
	}

	/**
	 * 添加套餐与商品的关联关系
	 *
	 * @param comboId 套餐 ID
	 * @param goodsId 商品 ID
	 * @return
	 * @author nianhua.jiang
	 * @date 2020/11/17 14:42
	 **/
	private void insertBasicComboGoods(Integer comboId, Integer goodsId) {
		if (goodsId != 0) {
			BasicComboGoods basicComboGoodsHardWare = new BasicComboGoods();
			//套餐ID
			basicComboGoodsHardWare.setComboId(comboId);
			//硬件权限商品ID
			basicComboGoodsHardWare.setGoodsId(goodsId);
			//商品数量
			basicComboGoodsHardWare.setQuantity(1);
			//是否是赠送商品
			basicComboGoodsHardWare.setGiftFlag("0");
			comboGoodsMapper.insert(basicComboGoodsHardWare);
		}
	}

	/**
	 * @param entity
	 * @return
	 * @author nianhua.jiang
	 * @date 2020/11/17 14:38
	 **/
	private int insertGoodsInfo(HardwareSale entity, String str, Integer productId, String unit) {

		BasicGoodsInfo goodsInfo = new BasicGoodsInfo();

		//商品名称
		goodsInfo.setName(str + entity.getHardwareDuration() + unit);
		//排序
		goodsInfo.setSort(1);
		//商品所属类别 ID 1-智能设备 2-虚拟商品
		goodsInfo.setCategoryId(2);
		//数量
		goodsInfo.setUnitCount(entity.getHardwareDuration());
		//单位
		goodsInfo.setUnit("天");
		//商品有效时长
		goodsInfo.setExpireDuration(entity.getHardwareDuration());
		//商品 product_id
		goodsInfo.setProductId(productId);
		//购买状态，0-可购买,1-不可购买
		goodsInfo.setStatus("1");
		//更新时间
		goodsInfo.setUpdateTime(LocalDateTime.now());
		//逻辑删除 0-正常
		goodsInfo.setDelFlag("0");
		//使用类型 0-永久 1-租赁
		goodsInfo.setUseType("1");
		//TODO goodsInfoHardware.setType();
		goodsInfoMapper.insert(goodsInfo);

		return goodsInfo.getId();

	}
	//TODO ===========================2020/11/17 nianhua.jiang ADD E-N-D =============================================//
}
